package facelets.component;



import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Locale;

import javax.faces.application.Application;
import javax.faces.component.UIOutput;
import javax.faces.component.UIViewRoot;
import javax.faces.event.ActionEvent;
import javax.faces.event.MethodExpressionActionListener;

import org.apache.commons.lang.WordUtils;
import org.apache.myfaces.component.html.ext.HtmlCommandLink;
import org.apache.myfaces.component.html.ext.HtmlOutputText;
import org.apache.myfaces.component.html.ext.HtmlPanelGrid;

import com.sun.facelets.FaceletContext;
import com.sun.facelets.tag.TagAttribute;
import com.sun.facelets.tag.jsf.ComponentConfig;
import com.sun.facelets.tag.jsf.html.HtmlComponentHandler;

/**
 * @author Nacho Estrada <nacho.estrada -at- xplayat.es> (website http://www.xplayat.es)
 *
 */
public class MonthCalendar extends HtmlComponentHandler { // NO_UCD
	
//	private final TagAttribute monthTag;
//	private final TagAttribute yearTag;
//	private final TagAttribute dayTooltipTag;
//	private final TagAttribute dayStyleClassTag;
//	private final TagAttribute dayStyleTag;
	private final TagAttribute dayNameStyleClassTag;
	private final TagAttribute dayNameStyleTag;
	private final TagAttribute actionListenerTag;
	
	public static final String MONTH = "month";
	public static final String YEAR = "year";
	public static final String DAY_TOOL_TIP = "dayTooltip";
	public static final String DAY_STYLE_CLASS = "dayStyleClass";
	public static final String DAY_STYLE = "dayStyle";
	private static final String DAY_NAME_STYLE_CLASS = "dayNameStyleClass";
	private static final String DAY_NAME_STYLE = "dayNameStyle";
	private static final String ACTION_LISTENER = "actionListener";
	
	
	public MonthCalendar(ComponentConfig cfg) {
		super(cfg);
//		monthTag = getAttribute(MONTH);
//		yearTag = getAttribute(YEAR);
//		dayTooltipTag = getAttribute(DAY_TOOL_TIP);
//		dayStyleClassTag = getAttribute(DAY_STYLE_CLASS);
//		dayStyleTag = getAttribute(DAY_STYLE);
		dayNameStyleClassTag = getAttribute(DAY_NAME_STYLE_CLASS);
		dayNameStyleTag = getAttribute(DAY_NAME_STYLE);
		actionListenerTag = getAttribute(ACTION_LISTENER);
	}
	/*
	 	@Override
	public void setAttributes(FaceletContext ctx, Object instance) {
		super.setAttributes(ctx, instance);
		
		ArrayList<String> dayTooltips = loadArrayList(dayTooltipTag, ctx);
		ArrayList<String> dayStyles = loadArrayList(dayStyleTag, ctx);
		ArrayList<String> dayStylesClass = loadArrayList(dayStyleClassTag, ctx);

		// Ajuste del calendario al mes requerido
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(new Date());
		int year =  yearTag!=null ? yearTag.getInt(ctx)	: gc.get(Calendar.YEAR);
		
		int	month = monthTag!=null ? monthTag.getInt(ctx)-1	: gc.get(Calendar.MONTH);
		gc.set(year, month, 1);

		HtmlPanelGrid panel = (HtmlPanelGrid) instance;
		panel.setColumns(7);
		
		Locale currentLocale = ctx.getFacesContext().getViewRoot().getLocale();
		DateFormatSymbols symbols = new DateFormatSymbols(currentLocale);
		
		// Facet header para el nombre del mes
		UIOutput f = (UIOutput)ctx.getFacesContext().getApplication().createComponent(UIOutput.COMPONENT_TYPE);
		f.setValue(WordUtils.capitalize(symbols.getMonths()[month]) + " " + year);
		panel.getFacets().put("header", f);
        
		// i18n para los dias de la semana
		String[] localeShortWeekdays = symbols.getShortWeekdays();
        String[] localeWeekdays = symbols.getWeekdays();
        String[][] weekdays = new String[7][2];        
		weekdays[0] = new String[]{localeWeekdays[Calendar.MONDAY], localeShortWeekdays[Calendar.MONDAY]};
        weekdays[1] = new String[]{localeWeekdays[Calendar.TUESDAY], localeShortWeekdays[Calendar.TUESDAY]};
        weekdays[2] = new String[]{localeWeekdays[Calendar.WEDNESDAY], localeShortWeekdays[Calendar.WEDNESDAY]};
        weekdays[3] = new String[]{localeWeekdays[Calendar.THURSDAY], localeShortWeekdays[Calendar.THURSDAY]};
        weekdays[4] = new String[]{localeWeekdays[Calendar.FRIDAY], localeShortWeekdays[Calendar.FRIDAY]};
        weekdays[5] = new String[]{localeWeekdays[Calendar.SATURDAY], localeShortWeekdays[Calendar.SATURDAY]};
        weekdays[6] = new String[]{localeWeekdays[Calendar.SUNDAY], localeShortWeekdays[Calendar.SUNDAY]};
        
        Application app = ctx.getFacesContext().getApplication();
        
        // Celdas con el nombre de los dias de la semana
		for ( String[] day: weekdays) {
			HtmlOutputText d = (HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);
			d.setValue(day[1]);
			d.setTitle(WordUtils.capitalize(day[0]));
			if ( dayNameStyleTag != null )
				d.setStyle(dayNameStyleTag.getValue(ctx));
			if ( dayNameStyleClassTag != null )
				d.setStyleClass(dayNameStyleClassTag.getValue(ctx));
			panel.getChildren().add(d);
		}
		
		// Celdas vacias para que el primer dia este en su lugar
		int min = (gc.get(Calendar.DAY_OF_WEEK)+5)%7;
		for ( int i = 0; i < min; i++ ) {
			HtmlOutputText d = (HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);
			d.setValue(" ");
			panel.getChildren().add(d);
		}
		
		// Celdas con los dias
		int max = gc.getActualMaximum(Calendar.DAY_OF_MONTH);
		for (int i = 1; i <= max; i ++ ) {
			HtmlCommandLink d;
			d = (HtmlCommandLink)app.createComponent(HtmlCommandLink.COMPONENT_TYPE);
			//d = (HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);
			
			
			if ( actionListenerTag!= null ) {
				MethodBinding mb = new LegacyMethodBinding(actionListenerTag.getMethodExpression(ctx, null, new Class[]{ActionEvent.class}));
				d.setActionListener(mb);
			} else 
				d.setDisabled(true);
			
			d.setValue(String.valueOf(i));
			d.setId("_" + i);
			if ( dayTooltips != null )
				d.setTitle(dayTooltips.get(i-1));
			if ( dayStyles != null )
				d.setStyle(dayStyles.get(i-1));
			if ( dayStylesClass != null )
				d.setStyleClass(dayStylesClass.get(i-1));
			
			panel.getChildren().add(d);
		}
		
		//Completo con celdas vacias la ultima fila para que el componente no de warnings
		while ( panel.getChildCount() % panel.getColumns() != 0) {
			HtmlOutputText d = (HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);
			panel.getChildren().add(d);
		}
		
		
		if ( getAttribute("styleClass") == null )
			panel.setStyleClass("block");
		if ( getAttribute("headerClass") == null )
			panel.setHeaderClass("blockheader");
	}
	 */
	
/*
 * (non-Javadoc)
 * @see com.sun.facelets.tag.MetaTagHandler#setAttributes(com.sun.facelets.FaceletContext, java.lang.Object)
 */
	@Override
	public void setAttributes(FaceletContext ctx, Object instance) {
		super.setAttributes(ctx, instance);
		HtmlPanelGrid panel = (HtmlPanelGrid) instance;
		
//		checkList(dayTooltipTag, ctx);
//		checkList(dayStyleTag, ctx);
//		checkList(dayStyleClassTag, ctx);
		
		panel.setColumns(7);
		UIViewRoot viewRoot = ctx.getFacesContext().getViewRoot();
		Locale currentLocale = viewRoot.getLocale();
		DateFormatSymbols symbols = new DateFormatSymbols(currentLocale);
		
		// Facet header para el nombre del mes
		UIOutput f = (UIOutput)ctx.getFacesContext().getApplication().createComponent(UIOutput.COMPONENT_TYPE);
		panel.getFacets().put("header", f);
        
		// i18n para los dias de la semana
		String[] localeShortWeekdays = symbols.getShortWeekdays();
        String[] localeWeekdays = symbols.getWeekdays();
        String[][] weekdays = new String[7][2];        
		weekdays[0] = new String[]{localeWeekdays[Calendar.MONDAY], localeShortWeekdays[Calendar.MONDAY]};
        weekdays[1] = new String[]{localeWeekdays[Calendar.TUESDAY], localeShortWeekdays[Calendar.TUESDAY]};
        weekdays[2] = new String[]{localeWeekdays[Calendar.WEDNESDAY], localeShortWeekdays[Calendar.WEDNESDAY]};
        weekdays[3] = new String[]{localeWeekdays[Calendar.THURSDAY], localeShortWeekdays[Calendar.THURSDAY]};
        weekdays[4] = new String[]{localeWeekdays[Calendar.FRIDAY], localeShortWeekdays[Calendar.FRIDAY]};
        weekdays[5] = new String[]{localeWeekdays[Calendar.SATURDAY], localeShortWeekdays[Calendar.SATURDAY]};
        weekdays[6] = new String[]{localeWeekdays[Calendar.SUNDAY], localeShortWeekdays[Calendar.SUNDAY]};
        
        Application app = ctx.getFacesContext().getApplication();
        
        // Celdas con el nombre de los dias de la semana
		for ( String[] day: weekdays) {
			HtmlOutputText d = (HtmlOutputText)app.createComponent(HtmlOutputText.COMPONENT_TYPE);
			d.setValue(day[1]);
			d.setTitle(WordUtils.capitalize(day[0]));
			if ( dayNameStyleTag != null )
				d.setStyle(dayNameStyleTag.getValue(ctx));
			if ( dayNameStyleClassTag != null )
				d.setStyleClass(dayNameStyleClassTag.getValue(ctx));
			panel.getChildren().add(d);
		}
		
		for ( int i = 0; i < 42; i++ ) {
			HtmlCommandLink d = (HtmlCommandLink)app.createComponent(HtmlCommandLink.COMPONENT_TYPE);
			if ( actionListenerTag!= null ) {
//				MethodBinding mb = new LegacyMethodBinding(actionListenerTag.getMethodExpression(ctx, null, new Class[]{ActionEvent.class}));
//				d.setActionListener(mb);
				MethodExpressionActionListener meal = new MethodExpressionActionListener(actionListenerTag.getMethodExpression(ctx, null, new Class[]{ActionEvent.class}));
				d.addActionListener(meal);
			} else 
				d.setDisabled(true);
			
			d.setId(this.getAttribute("id").getValue(ctx) + "_" + i);
			panel.getChildren().add(d);
		}
		
				
		if ( getAttribute("styleClass") == null )
			panel.setStyleClass("block");
		if ( getAttribute("headerClass") == null )
			panel.setHeaderClass("blockheader");
	}
	
/*	private void checkList ( TagAttribute tag, FaceletContext ctx ) {
		if ( tag !=null ) {
			Object values = tag.getObject(ctx);
			if ( !(values instanceof Iterable) && !(values instanceof Object[]) ) {
				throw new TagAttributeException(this.tag,
						tag, tag.getValue() + " must be an array or an iterable object");
			}
		}
	}
*/
/*		
	protected MetaRuleset createMetaRuleset(Class type) {
		MetaRuleset m = super.createMetaRuleset(type);
        m.ignore("month");
        m.ignore("year");
        m.ignore("dayNameStyleClass");
        m.ignore("dayNameStyle");
        m.ignore("actionListener");
        return m;
        
    }
*/
}	
		